Add support for "Raymarine Waypoint File".
authoroliskoli <oliskoli>
Sun, 26 Nov 2006 19:39:23 +0000 (19:39 +0000)
committeroliskoli <oliskoli>
Sun, 26 Nov 2006 19:39:23 +0000 (19:39 +0000)
Makefile.in
raymarine.c [new file with mode: 0644]
reference/raymarine-sample.gpx [new file with mode: 0644]
reference/raymarine-sample.rwf [new file with mode: 0644]
testo
vecs.c
xmldoc/formats/raymarine.xml [new file with mode: 0644]

index 1294a981fad9e536f39a95544bc7f13d16004e7a..054a1911a5021f415a8fcb48830f50085cc02ca8 100644 (file)
@@ -54,7 +54,7 @@ FMTS=magproto.o gpx.o geo.o mapsend.o mapsource.o garmin_tables.o \
        tef_xml.o maggeo.o pathaway.o vitosmt.o gdb.o bcr.o coto.o \
        ignrando.o stmwpp.o msroute.o cst.o nmn4.o mag_pdb.o compegps.o \
        yahoo.o unicsv.o wfff_xml.o garmin_txt.o axim_gpb.o gpssim.o \
-       wbt-200.o stmsdf.o gtrnctr.o dmtlog.o
+       wbt-200.o stmsdf.o gtrnctr.o dmtlog.o raymarine.o
 
 FILTERS=position.o radius.o duplicate.o arcdist.o polygon.o smplrout.o \
        reverse_route.o sort.o stackfilter.o trackfilter.o discard.o \
@@ -553,6 +553,8 @@ quovadis.o: quovadis.c quovadis.h defs.h config.h queue.h gbtypes.h \
   coldsync/palm.h coldsync/../gbtypes.h coldsync/pdb.h
 radius.o: radius.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \
   zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h filterdefs.h grtcirc.h
+raymarine.o: raymarine.c defs.h config.h queue.h gbtypes.h cet.h cet_util.h \
+  inifile.h filterdefs.h grtcirc.h gbfile.h csv_util.h
 reverse_route.o: reverse_route.c defs.h config.h queue.h gbtypes.h \
   zlib/zlib.h zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h \
   filterdefs.h
diff --git a/raymarine.c b/raymarine.c
new file mode 100644 (file)
index 0000000..b516fd0
--- /dev/null
@@ -0,0 +1,474 @@
+ /*
+
+    Support for Raymarine Waypoint File (.rwf).
+
+    Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+*/
+
+/*  
+    Known format limits:
+
+       Waypoint name: max. 16 characters
+       Routes:        max. 50 waypoints per route
+
+    History:
+       
+       2006/10/30: Initial release (not yet in GPSBabel source tree)
+       2006/11/08: 
+*/
+
+#include "defs.h"
+#include "inifile.h"
+#include "csv_util.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef unsigned long long guid_t;
+
+static inifile_t *fin;
+static gbfile *fout;
+static waypoint **depot;
+static short_handle hshort;
+static int size_of_depot, items_in_depot;
+static int rte_index, rte_wpt_index;
+static char *sguid;
+static char *opt_location;
+
+#define MYNAME "raymarine"
+
+static
+arglist_t raymarine_args[] = 
+{
+       { "location", &opt_location, "Default location", "New location", ARGTYPE_STRING, ARG_NOMINMAX },
+       ARG_TERMINATOR
+};
+
+/* from csv_util.c: convert excel time (days since 1900) to time_t and back again */
+
+#define EXCEL_TO_TIMET(a) ((a - 25569.0) * 86400.0)
+#define TIMET_TO_EXCEL(a) ((a / 86400.0) + 25569.0)
+
+/* Bitmaps */
+
+typedef struct {
+       int id;
+       char *name;
+} raymarine_symbol_mapping_t;
+
+static raymarine_symbol_mapping_t raymarine_symbols[] = {
+       { 0, "Unknown Symbol 0" },
+       { 1, "Unknown Symbol 1" },
+       { 2, "Unknown Symbol 2" },
+       { 3, "Red Square" },
+       { 4, "Big Fish" },
+       { 5, "Anchor" },
+       { 6, "Smiley" },
+       { 7, "Sad" },
+       { 8, "Red Button" },
+       { 9, "Sailfish" },
+       { 10, "Danger" },
+       { 11, "Attention" },
+       { 12, "Black Square" },
+       { 13, "Intl. Dive Flag" },
+       { 14, "Vessel" },
+       { 15, "Lobster" },
+       { 16, "Buoy" },
+       { 17, "Exclamation" },
+       { 18, "Red X" },
+       { 19, "Check Mark" },
+       { 20, "Black Plus" },
+       { 21, "Black Cross" },
+       { 22, "MOB" },
+       { 23, "Billfish" },
+       { 24, "Bottom Mark" },
+       { 25, "Circle" },
+       { 26, "Diamond" },
+       { 27, "Diamond Quarters" },
+       { 28, "U.S.Dive Flag" },
+       { 29, "Dolphin" },
+       { 30, "Few Fish" },
+       { 31, "Multiple Fish" },
+       { 32, "Many Fish" },
+       { 33, "Single Fish" },
+       { 34, "Small Fish" },
+       { 35, "Marker" },
+       { 36, "Cocktails" },
+       { 37, "Red Box Marker" },
+       { 38, "Reef" },
+       { 39, "Rocks" },
+       { 40, "FishSchool" },
+       { 41, "Seaweed" },
+       { 42, "Shark" },
+       { 43, "Sportfisher" },
+       { 44, "Swimmer" },
+       { 45, "Top Mark" },
+       { 46, "Trawler" },
+       { 47, "Tree" },
+       { 48, "Triangle" },
+       { 49, "Wreck" }
+};
+
+#define RAYMARINE_SYMBOL_CT  sizeof(raymarine_symbols) / sizeof(raymarine_symbol_mapping_t)
+#define RAYMARINE_STD_SYMBOL 3
+
+static int
+find_symbol_num(const char *descr)
+{
+       if ((descr != NULL) && (*descr)) {
+               
+               int i;
+               raymarine_symbol_mapping_t *a;
+               
+               a = &raymarine_symbols[0];
+               
+               for (i = 0; i < RAYMARINE_SYMBOL_CT; i++, a++) {
+                       printf(MYNAME ": %s - %s\n", descr, a->name);
+                       if (case_ignore_strcmp(descr, a->name) == 0) return i;
+               }
+       }
+       
+       return RAYMARINE_STD_SYMBOL;
+}
+
+/* ============================================= */
+/* %%%    R A Y M A R I N E   R E A D E R    %%% */
+/* ============================================= */
+
+static void
+raymarine_rd_init(const char *fname)
+{
+       fin = inifile_init(fname, MYNAME);
+}
+
+static void
+raymarine_rd_done(void)
+{
+       inifile_done(fin);
+}
+
+static void
+raymarine_read(void)
+{
+       waypoint *wpt;
+       int ix, rx;
+       
+       /* Read all waypoints */
+       
+       for (ix = 0; ix < 0x3FFF; ix++) {
+               char sect[10];
+               char *str, *name, *lat, *lon;
+               
+               /* built section identifier */
+               snprintf(sect, sizeof(sect), "Wp%d", ix);
+               
+               /* try to read our most expected values */
+               if (NULL == (name = inifile_readstr(fin, sect, "Name"))) break;
+               if (NULL == (lat = inifile_readstr(fin, sect, "Lat"))) break;
+               if (NULL == (lon = inifile_readstr(fin, sect, "Long"))) break;
+               
+               wpt = waypt_new();
+               wpt->shortname = xstrdup(name);
+               wpt->latitude = atof(lat);
+               wpt->longitude = atof(lon);
+               waypt_add(wpt);
+               
+               /* try to read optional values */
+               if (((str = inifile_readstr(fin, sect, "Notes"))) && *str) wpt->notes = xstrdup(str);
+               if (((str = inifile_readstr(fin, sect, "Time"))) && *str) wpt->creation_time = EXCEL_TO_TIMET(atof(str));
+               if (((str = inifile_readstr(fin, sect, "Bmp"))) && *str) {
+                       int symbol = atoi(str);
+                       
+                       if ((symbol < 3) && (symbol >= RAYMARINE_SYMBOL_CT))
+                               symbol = RAYMARINE_STD_SYMBOL;
+                       wpt->icon_descr = raymarine_symbols[symbol].name;
+               }
+       }
+       
+       /* Read all routes */
+       
+       for (rx = 0; rx < 0x3FFF; rx++) {
+               char sect[10];
+               char *name;
+               route_head *rte;
+               int wx;
+
+               snprintf(sect, sizeof(sect), "Rt%d", rx);
+               if (NULL == (name = inifile_readstr(fin, sect, "Name"))) break;
+               
+               rte = route_head_alloc();
+               rte->rte_name = xstrdup(name);
+               route_add_head(rte);
+               
+               for (wx = 0; wx < 0x3FFF; wx++) {
+                       char buff[32];
+                       char *str;
+                       waypoint * wpt;
+                       
+                       snprintf(buff, sizeof(buff), "Mk%d", wx);
+                       str = inifile_readstr(fin, sect, buff);
+                       if ((str == NULL) || (*str == '\0')) break;
+                       
+                       wpt = find_waypt_by_name(str);
+                       if (wpt == NULL)
+                               fatal(MYNAME ": No associated waypoint for route point %s (Route %s)!\n",
+                                       str, rte->rte_name);
+                                       
+                       route_add_wpt(rte, waypt_dupe(wpt));
+               }
+       }
+}
+
+/* ============================================= */
+/* %%%    R A Y M A R I N E   W R I T E R    %%% */
+/* ============================================= */
+
+
+static guid_t
+mkGUID(void)
+{
+       guid_t res;
+       
+       if (gpsbabel_now != 0) {
+               srand(gpsbabel_now + rand());
+               res = ((guid_t) (gpsbabel_now) << 48) | 
+                       ((guid_t)(rand() & 0xFFFF) << 32) | 
+                       ((guid_t)(rand() & 0xFFFF) << 16) | 
+                       (rand() & 0xFFFF);
+       }
+       else res = 0;
+       
+       return res;
+}
+
+static char *
+GUID2str(guid_t GUID)
+{
+       gbuint16 w0, w1, w2, w3;
+       char *res;
+       
+       w0 = GUID & 0xFFFF; GUID = GUID >> 16;
+       w1 = GUID & 0xFFFF; GUID = GUID >> 16;
+       w2 = GUID & 0xFFFF; GUID = GUID >> 16;
+       w3 = GUID & 0xFFFF;
+       
+       xasprintf(&res, "%d-%d-%d-%d", w0, w1, w2, w3);
+       return res;
+}
+
+
+static void
+register_waypoint(const waypoint *wpt)
+{
+       int i;
+       
+       for (i = 0; i < items_in_depot; i++) {
+               waypoint *cmp = depot[i];
+               if ((strcmp(wpt->shortname, cmp->shortname) == 0) &&
+                   (wpt->latitude == cmp->latitude) &&
+                   (wpt->longitude == cmp->longitude))
+                       return;
+       }
+       
+       if (items_in_depot >= size_of_depot) {
+               size_of_depot+=16;
+               depot = (void *) xrealloc(depot, size_of_depot * sizeof(wpt));
+       }
+       
+       depot[items_in_depot] = (waypoint *)wpt;
+       items_in_depot++;
+}
+
+static void
+write_waypoint(gbfile *fout, const waypoint *wpt, const int waypt_no, const char *location, const char *GUID)
+{
+       char *notes;
+       char *temp;
+       double time;
+               
+       /* ToDo: remove possible line-breaks from notes */
+       
+       notes = (wpt->notes != NULL) ? wpt->notes : "";
+       time = (wpt->creation_time != 0) ? TIMET_TO_EXCEL(wpt->creation_time) : TIMET_TO_EXCEL(gpsbabel_time);
+       
+       temp = mkshort(hshort, wpt->shortname);
+       gbfprintf(fout, "[Wp%d]\n"
+                       "Loc=%s\n"
+                       "Name=%s\n"
+                       "Lat=%.15f\n"
+                       "Long=%.15f\n",
+               waypt_no, location, temp, wpt->latitude, wpt->longitude
+       );
+       xfree(temp);
+       gbfprintf(fout, "Rng=%.15f\n"
+                       "Bear=%.15f\n"
+                       "Bmp=%d\n"
+                       "Fixed=1\n"
+                       "Locked=0\n"
+                       "Notes=%s\n",
+               0.0, 0.0, 
+               find_symbol_num(wpt->icon_descr), 
+               notes
+       );
+       gbfprintf(fout, "Rel=\n"
+                       "RelSet=1\n"
+                       "RcCount=1\n"
+                       "RcRadius=%.15f\n"
+                       "Show=1\n"
+                       "RcShow=0\n"
+                       "SeaTemp=%.15f\n"
+                       "Depth=%.15f\n"
+                       "Time=%.15f\n"
+                       "GUID=%s\n",
+               0.0, -32678.0, 65535.0, time, GUID
+       );
+}
+
+static void
+write_route_head_cb(const route_head *rte)
+{
+       gbfprintf(fout, "[Rt%d]\n"
+                       "Name=%s\n"
+                       "Visible=1\n"
+                       "Guid=%s\n",
+               rte_index,
+               rte->rte_name,
+               sguid
+       );
+       rte_index++;
+       rte_wpt_index = 0;
+}
+
+static void
+write_route_wpt_cb(const waypoint *wpt)
+{
+       int i;
+       char *s;
+       static char *items[] = {
+               "Cog",
+               "Eta",
+               "Length"
+               "PredictedDrift",
+               "PredictedSet",
+               "PredictedSog",
+               "PredictedTime",
+               "PredictedTwa2",
+               "PredictedTwd",
+               "PredictedTws" };
+               
+       s = mkshort(hshort, wpt->shortname);
+       gbfprintf(fout, "Mk%d=%s\n", rte_wpt_index, wpt->shortname);
+       xfree(s);
+
+       for (i = 0; i < sizeof(items) / sizeof(char *); i++) {
+               gbfprintf(fout, "%s%d=%.15f\n", items[i], rte_wpt_index, 0.0);
+       }
+       rte_wpt_index++;
+}
+
+static void
+enum_route_hdr_cb(const route_head *rte)
+{
+       is_fatal(rte->rte_waypt_ct > 50,
+               MYNAME ": Routes with more than 50 points are not supported by Waymarine!");
+}
+
+static void
+enum_route_wpt_cb(const waypoint *wpt)
+{
+       register_waypoint(wpt);
+}
+
+static void
+raymarine_wr_init(const char *fname)
+{
+       fout = gbfopen(fname, "w", MYNAME);
+
+       hshort = mkshort_new_handle();
+       setshort_length(hshort, 16);
+
+       setshort_badchars(hshort, ",");
+       setshort_mustupper(hshort, 0);
+       setshort_mustuniq(hshort, 1);
+       setshort_whitespace_ok(hshort, 1);
+       setshort_repeating_whitespace_ok(hshort, 1);
+}
+
+static void
+raymarine_wr_done(void)
+{
+       mkshort_del_handle(&hshort);
+       gbfclose(fout);
+}
+
+static void
+raymarine_write(void)
+{
+       int i;
+       queue *elem, *tmp;
+       extern queue waypt_head;
+       guid_t guid;
+       
+       size_of_depot = 0;
+       items_in_depot = 0;
+       depot = NULL;
+       guid = mkGUID();
+       sguid = GUID2str(guid);
+
+       /* enumerate all possible waypoints */
+       QUEUE_FOR_EACH(&waypt_head, elem, tmp) {
+               waypoint *wpt = (waypoint *) elem;
+               register_waypoint(wpt);
+       }
+       route_disp_all(enum_route_hdr_cb, NULL, enum_route_wpt_cb);
+       
+       /* write out waypoint summary */
+       for (i = 0; i < items_in_depot; i++) {
+               waypoint *wpt = depot[i];
+               write_waypoint(fout, wpt, i, opt_location, sguid);
+       }
+       
+       /* write out all routes with their waypoints */
+       rte_index = 0;
+       route_disp_all(write_route_head_cb, NULL, write_route_wpt_cb);
+       
+       if (depot != NULL) xfree(depot);
+       xfree(sguid);
+}
+
+/* ================================================== */
+/* %%%    M O D U L E   R E G I S T R A T I O N   %%% */
+/* ================================================== */
+
+ff_vecs_t raymarine_vecs = {
+       ff_type_file,
+       { 
+               ff_cap_read | ff_cap_write      /* waypoints */, 
+               ff_cap_none                     /* tracks */, 
+               ff_cap_read | ff_cap_write      /* routes */, 
+       },
+       raymarine_rd_init,
+       raymarine_wr_init,
+       raymarine_rd_done,
+       raymarine_wr_done,
+       raymarine_read,
+       raymarine_write,
+       NULL,
+       raymarine_args,
+       CET_CHARSET_ASCII, 0
+};
diff --git a/reference/raymarine-sample.gpx b/reference/raymarine-sample.gpx
new file mode 100644 (file)
index 0000000..cb130d3
--- /dev/null
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gpx
+ version="1.0"
+creator="GPSBabel - http://www.gpsbabel.org"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.topografix.com/GPX/1/0"
+xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
+<time>1970-01-01T00:00:00Z</time>
+<bounds minlat="48.623286047" minlon="9.895914981" maxlat="51.593568734" maxlon="12.598730495"/>
+<wpt lat="51.593568734" lon="9.895914981">
+<time>2006-11-06T21:07:41Z</time>
+  <name>Qr1-one</name>
+  <cmt>Qr1-one</cmt>
+  <desc>notes-1</desc>
+  <sym>Red Square</sym>
+</wpt>
+<wpt lat="50.833425048" lon="10.364770734">
+<time>2006-11-06T21:07:41Z</time>
+  <name>Qr,2</name>
+  <cmt>Qr,2</cmt>
+  <desc>notes-2</desc>
+  <sym>Big Fish</sym>
+</wpt>
+<wpt lat="50.184475274" lon="10.557828985">
+<time>2006-11-06T21:07:41Z</time>
+  <name>Qr3</name>
+  <cmt>Qr3</cmt>
+  <desc>notes-3</desc>
+  <sym>Anchor</sym>
+</wpt>
+<wpt lat="48.986577919" lon="12.047135492">
+<time>2006-11-06T21:07:41Z</time>
+  <name>Qr4-four</name>
+  <cmt>Qr4-four</cmt>
+  <desc>notes-4</desc>
+  <sym>Smiley</sym>
+</wpt>
+<wpt lat="48.623286047" lon="12.598730495">
+<time>2006-11-06T21:07:43Z</time>
+  <name>Qr5</name>
+  <cmt>Qr5</cmt>
+  <desc>notes-5</desc>
+  <sym>Sad</sym>
+</wpt>
+<rte>
+  <name>Qr</name>
+  <rtept lat="51.593568734" lon="9.895914981">
+<time>2006-11-06T21:07:41Z</time>
+    <name>Qr1-one</name>
+    <cmt>Qr1-one</cmt>
+    <desc>notes-1</desc>
+    <sym>Red Square</sym>
+  </rtept>
+  <rtept lat="50.833425048" lon="10.364770734">
+<time>2006-11-06T21:07:41Z</time>
+    <name>Qr,2</name>
+    <cmt>Qr,2</cmt>
+    <desc>notes-2</desc>
+    <sym>Big Fish</sym>
+  </rtept>
+  <rtept lat="50.184475274" lon="10.557828985">
+<time>2006-11-06T21:07:41Z</time>
+    <name>Qr3</name>
+    <cmt>Qr3</cmt>
+    <desc>notes-3</desc>
+    <sym>Anchor</sym>
+  </rtept>
+  <rtept lat="48.986577919" lon="12.047135492">
+<time>2006-11-06T21:07:41Z</time>
+    <name>Qr4-four</name>
+    <cmt>Qr4-four</cmt>
+    <desc>notes-4</desc>
+    <sym>Smiley</sym>
+  </rtept>
+  <rtept lat="48.623286047" lon="12.598730495">
+<time>2006-11-06T21:07:43Z</time>
+    <name>Qr5</name>
+    <cmt>Qr5</cmt>
+    <desc>notes-5</desc>
+    <sym>Sad</sym>
+  </rtept>
+</rte>
+</gpx>
diff --git a/reference/raymarine-sample.rwf b/reference/raymarine-sample.rwf
new file mode 100644 (file)
index 0000000..5657d28
--- /dev/null
@@ -0,0 +1,164 @@
+[Wp0]\r
+Loc=Qr\r
+Name=Qr1-one\r
+Lat=51.593568734471624\r
+Long=9.895914981396029\r
+Rng=0.000000000000000\r
+Bear=0.000000000000000\r
+Bmp=3\r
+Fixed=1\r
+Locked=0\r
+Notes=notes-1\r
+Rel=\r
+RelSet=1\r
+RcCount=1\r
+RcRadius=0.000000000000000\r
+Show=0\r
+RcShow=0\r
+SeaTemp=-32678.000000000000000\r
+Depth=65535.000000000000000\r
+Time=39027.880335648151000\r
+GUID=41847-17743-33206-33476\r
+[Wp1]\r
+Loc=Qr\r
+Name=Qr,2\r
+Lat=50.833425047658316\r
+Long=10.364770733812209\r
+Rng=0.000000000000000\r
+Bear=0.000000000000000\r
+Bmp=4\r
+Fixed=1\r
+Locked=0\r
+Notes=notes-2\r
+Rel=\r
+RelSet=1\r
+RcCount=1\r
+RcRadius=0.000000000000000\r
+Show=0\r
+RcShow=0\r
+SeaTemp=-32678.000000000000000\r
+Depth=65535.000000000000000\r
+Time=39027.880347222221000\r
+GUID=41847-17743-33462-33476\r
+[Wp2]\r
+Loc=Qr\r
+Name=Qr3\r
+Lat=50.184475273537196\r
+Long=10.557828984807108\r
+Rng=0.000000000000000\r
+Bear=0.000000000000000\r
+Bmp=5\r
+Fixed=1\r
+Locked=0\r
+Notes=notes-3\r
+Rel=\r
+RelSet=1\r
+RcCount=1\r
+RcRadius=0.000000000000000\r
+Show=0\r
+RcShow=0\r
+SeaTemp=-32678.000000000000000\r
+Depth=65535.000000000000000\r
+Time=39027.880347222221000\r
+GUID=41847-17743-33718-33476\r
+[Wp3]\r
+Loc=Qr\r
+Name=Qr4-four\r
+Lat=48.986577919201942\r
+Long=12.047135492482036\r
+Rng=0.000000000000000\r
+Bear=0.000000000000000\r
+Bmp=6\r
+Fixed=1\r
+Locked=0\r
+Notes=notes-4\r
+Rel=\r
+RelSet=1\r
+RcCount=1\r
+RcRadius=0.000000000000000\r
+Show=0\r
+RcShow=0\r
+SeaTemp=-32678.000000000000000\r
+Depth=65535.000000000000000\r
+Time=39027.880347222221000\r
+GUID=41847-17743-33974-33476\r
+[Wp4]\r
+Loc=Qr\r
+Name=Qr5\r
+Lat=48.623286046917791\r
+Long=12.598730495324602\r
+Rng=0.000000000000000\r
+Bear=0.000000000000000\r
+Bmp=7\r
+Fixed=1\r
+Locked=0\r
+Notes=notes-5\r
+Rel=\r
+RelSet=1\r
+RcCount=1\r
+RcRadius=0.000000000000000\r
+Show=0\r
+RcShow=0\r
+SeaTemp=-32678.000000000000000\r
+Depth=65535.000000000000000\r
+Time=39027.880358796298000\r
+GUID=41847-17743-34230-33476\r
+[Rt0]\r
+Name=Qr\r
+Visible=0\r
+Guid=41847-17743-32950-33476\r
+Mk0=Qr1-one\r
+Cog0=0.000000000000000\r
+Eta0=0.000000000000000\r
+Length0=0.000000000000000\r
+PredictedDrift0=0.000000000000000\r
+PredictedSet0=0.000000000000000\r
+PredictedSog0=0.000000000000000\r
+PredictedTime0=0.000000000000000\r
+PredictedTwa0=0.000000000000000\r
+PredictedTwd0=0.000000000000000\r
+PredictedTws0=0.000000000000000\r
+Mk1=Qr,2\r
+Cog1=0.000000000000000\r
+Eta1=0.000000000000000\r
+Length1=0.000000000000000\r
+PredictedDrift1=0.000000000000000\r
+PredictedSet1=0.000000000000000\r
+PredictedSog1=0.000000000000000\r
+PredictedTime1=0.000000000000000\r
+PredictedTwa1=0.000000000000000\r
+PredictedTwd1=0.000000000000000\r
+PredictedTws1=0.000000000000000\r
+Mk2=Qr3\r
+Cog2=0.000000000000000\r
+Eta2=0.000000000000000\r
+Length2=0.000000000000000\r
+PredictedDrift2=0.000000000000000\r
+PredictedSet2=0.000000000000000\r
+PredictedSog2=0.000000000000000\r
+PredictedTime2=0.000000000000000\r
+PredictedTwa2=0.000000000000000\r
+PredictedTwd2=0.000000000000000\r
+PredictedTws2=0.000000000000000\r
+Mk3=Qr4-four\r
+Cog3=0.000000000000000\r
+Eta3=0.000000000000000\r
+Length3=0.000000000000000\r
+PredictedDrift3=0.000000000000000\r
+PredictedSet3=0.000000000000000\r
+PredictedSog3=0.000000000000000\r
+PredictedTime3=0.000000000000000\r
+PredictedTwa3=0.000000000000000\r
+PredictedTwd3=0.000000000000000\r
+PredictedTws3=0.000000000000000\r
+Mk4=Qr5\r
+Cog4=0.000000000000000\r
+Eta4=0.000000000000000\r
+Length4=0.000000000000000\r
+PredictedDrift4=0.000000000000000\r
+PredictedSet4=0.000000000000000\r
+PredictedSog4=0.000000000000000\r
+PredictedTime4=0.000000000000000\r
+PredictedTwa4=0.000000000000000\r
+PredictedTwd4=0.000000000000000\r
+PredictedTws4=0.000000000000000\r
diff --git a/testo b/testo
index d43841c42b34e8af223226ac2b9c48d44ba8d452..8cf5b64f3310d7a8812b25bda062ff7cfaf498b8 100755 (executable)
--- a/testo
+++ b/testo
@@ -1150,5 +1150,11 @@ compare ${TMPDIR}/transform-rte.gpx ${REFERENCE}/transform-rte.gpx
 ${PNAME} -i gpx -f ${REFERENCE}/expertgps.gpx -x nuketypes,waypoints,tracks -x transform,wpt=rte,del=y -o gpx -F ${TMPDIR}/transform-wpt.gpx
 compare ${TMPDIR}/transform-wpt.gpx ${REFERENCE}/transform-wpt.gpx
 
+#
+# "Raymarine Waypoint File" tests
+#
+${PNAME} -i raymarine -f ${REFERENCE}/raymarine-sample.rwf -o gpx -F ${TMPDIR}/raymarine-sample.gpx
+compare ${TMPDIR}/raymarine-sample.gpx ${REFERENCE}/raymarine-sample.gpx
+
 
 exit 0
diff --git a/vecs.c b/vecs.c
index 7d3befe36360924aeb143e66cbae2507a870b5fa..f8520a232346d0fe8b0bafaa43206290cfe3d256 100644 (file)
--- a/vecs.c
+++ b/vecs.c
@@ -111,6 +111,7 @@ extern ff_vecs_t wbt_svecs;
 extern ff_vecs_t wbt_fvecs;
 extern ff_vecs_t gtc_vecs;
 extern ff_vecs_t dmtlog_vecs;
+extern ff_vecs_t raymarine_vecs;
 
 static
 vecs_t vec_list[] = {
@@ -607,6 +608,12 @@ vecs_t vec_list[] = {
                "TrackLogs digital mapping (.trl)",
                "trl"
        },
+       {
+               &raymarine_vecs,
+               "raymarine",
+               "Raymarine Waypoint File (.rwf)",
+               "rwf"
+       },
        {
                NULL,
                NULL,
diff --git a/xmldoc/formats/raymarine.xml b/xmldoc/formats/raymarine.xml
new file mode 100644 (file)
index 0000000..258c12e
--- /dev/null
@@ -0,0 +1,7 @@
+<para>
+  This format supports the "Raymarine Waypoint File" format (.rwf).
+  More information to Raymarine you'll find at their <ulink url="http://www.raymarine.com">homepage</ulink>.
+</para>
+<para>
+  Known limits: max. 16 characters for waypoint names and max. 50 waypoints per route.
+</para>